home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / pascal / pasc_2.z / pasc_2
Internet Message Format  |  1994-10-24  |  57KB

  1. From steven@cwi.nl Sat Oct  5 20:17:57 1991
  2. Newsgroups: comp.sources.misc
  3. From: steven@cwi.nl (Steven Pemberton)
  4. Subject:  v23i026:  pascal - Public domain Pascal Compiler and Interpreter, Part02/03
  5. Followup-To: comp.sources.d
  6. X-Md4-Signature: 7631e6c5630aff576b3785529c06f66c
  7. Organization: Sterling Software, IMD
  8. Date: Fri, 27 Sep 1991 04:12:14 GMT
  9.  
  10. Submitted-by: steven@cwi.nl (Steven Pemberton)
  11. Posting-number: Volume 23, Issue 26
  12. Archive-name: pascal/part02
  13. Environment: pascal
  14.  
  15. #!/bin/sh
  16. # do not concatenate these parts, unpack them in order with /bin/sh
  17. # file pcom.p continued
  18. #
  19. if test ! -r _shar_seq_.tmp; then
  20.     echo 'Please unpack part 1 first!'
  21.     exit 1
  22. fi
  23. (read Scheck
  24.  if test "$Scheck" != 2; then
  25.     echo Please unpack part "$Scheck" next!
  26.     exit 1
  27.  else
  28.     exit 0
  29.  fi
  30. ) < _shar_seq_.tmp || exit 1
  31. if test ! -f _shar_wnt_.tmp; then
  32.     echo 'x - still skipping pcom.p'
  33. else
  34. echo 'x - continuing file pcom.p'
  35. sed 's/^X//' << 'SHAR_EOF' >> 'pcom.p' &&
  36. X                end
  37. X            until sy <> comma;
  38. X            if sy = colon then
  39. X              begin insymbol;
  40. X                if sy = ident then
  41. X                  begin searchid([types],lcp);
  42. X                lsp := lcp^.idtype;
  43. X                if lsp <> nil then
  44. X                 if not(lsp^.form in[scalar,subrange,pointer])
  45. X                    then begin error(120); lsp := nil end;
  46. X                lcp3 := lcp2;
  47. X                while lcp2 <> nil do
  48. X                  begin lcp2^.idtype := lsp; lcp := lcp2;
  49. X                    lcp2 := lcp2^.next
  50. X                  end;
  51. X                lcp^.next := lcp1; lcp1 := lcp3;
  52. X                insymbol
  53. X                  end
  54. X                else error(2);
  55. X                if not (sy in fsys + [semicolon,rparent]) then
  56. X                  begin error(7);skip(fsys+[semicolon,rparent])end
  57. X              end
  58. X            else error(5)
  59. X              end
  60. X            else
  61. X              begin
  62. X            if sy = varsy then
  63. X              begin lkind := formal; insymbol end
  64. X            else lkind := actual;
  65. X            lcp2 := nil;
  66. X            count := 0;
  67. X            repeat
  68. X              if sy = ident then
  69. X                begin new(lcp,vars);
  70. X                  with lcp^ do
  71. X                begin name:=id; idtype:=nil; klass:=vars;
  72. X                  vkind := lkind; next := lcp2; vlev := level;
  73. X                end;
  74. X                  enterid(lcp);
  75. X                  lcp2 := lcp; count := count+1;
  76. X                  insymbol;
  77. X                end;
  78. X              if not (sy in [comma,colon] + fsys) then
  79. X                begin error(7);skip(fsys+[comma,semicolon,rparent])
  80. X                end;
  81. X              test := sy <> comma;
  82. X              if not test then insymbol
  83. X            until test;
  84. X            if sy = colon then
  85. X              begin insymbol;
  86. X                if sy = ident then
  87. X                  begin searchid([types],lcp);
  88. X                lsp := lcp^.idtype;
  89. X                lsize := ptrsize;
  90. X                if lsp <> nil then
  91. X                  if lkind=actual then
  92. X                    if lsp^.form<=power then lsize := lsp^.size
  93. X                    else if lsp^.form=files then error(121);
  94. X                align(parmptr,lsize);
  95. X                lcp3 := lcp2;
  96. X                align(parmptr,lc);
  97. X                lc := lc+count*lsize;
  98. X                llc := lc;
  99. X                while lcp2 <> nil do
  100. X                  begin lcp := lcp2;
  101. X                    with lcp2^ do
  102. X                      begin idtype := lsp;
  103. X                    llc := llc-lsize;
  104. X                    vaddr := llc;
  105. X                      end;
  106. X                    lcp2 := lcp2^.next
  107. X                  end;
  108. X                lcp^.next := lcp1; lcp1 := lcp3;
  109. X                insymbol
  110. X                  end
  111. X                else error(2);
  112. X                if not (sy in fsys + [semicolon,rparent]) then
  113. X                  begin error(7);skip(fsys+[semicolon,rparent])end
  114. X              end
  115. X            else error(5);
  116. X              end;
  117. X          end;
  118. X        if sy = semicolon then
  119. X          begin insymbol;
  120. X            if not (sy in fsys + [ident,varsy,procsy,funcsy]) then
  121. X              begin error(7); skip(fsys + [ident,rparent]) end
  122. X          end
  123. X          end (*while*) ;
  124. X        if sy = rparent then
  125. X          begin insymbol;
  126. X        if not (sy in fsy + fsys) then
  127. X          begin error(6); skip(fsy + fsys) end
  128. X          end
  129. X        else error(4);
  130. X        lcp3 := nil;
  131. X        (*reverse pointers and reserve local cells for copies of multiple
  132. X         values*)
  133. X        while lcp1 <> nil do
  134. X          with lcp1^ do
  135. X        begin lcp2 := next; next := lcp3;
  136. X          if klass = vars then
  137. X            if idtype <> nil then
  138. X              if (vkind=actual)and(idtype^.form>power) then
  139. X            begin align(idtype,lc);
  140. X              vaddr := lc;
  141. X              lc := lc+idtype^.size;
  142. X            end;
  143. X          lcp3 := lcp1; lcp1 := lcp2
  144. X        end;
  145. X        fpar := lcp3
  146. X      end
  147. X        else fpar := nil
  148. X    end (*parameterlist*) ;
  149. X
  150. X    begin (*procdeclaration*)
  151. X      llc := lc; lc := lcaftermarkstack; forw := false;
  152. X      if sy = ident then
  153. X    begin searchsection(display[top].fname,lcp); (*decide whether forw.*)
  154. X      if lcp <> nil then
  155. X        begin
  156. X          if lcp^.klass = proc then
  157. X        forw := lcp^.forwdecl and(fsy=procsy)and(lcp^.pfkind=actual)
  158. X          else
  159. X        if lcp^.klass = func then
  160. X          forw:=lcp^.forwdecl and(fsy=funcsy)and(lcp^.pfkind=actual)
  161. X        else forw := false;
  162. X          if not forw then error(160)
  163. X        end;
  164. X      if not forw then
  165. X        begin
  166. X          if fsy = procsy then new(lcp,proc,declared,actual)
  167. X          else new(lcp,func,declared,actual);
  168. X          with lcp^ do
  169. X        begin name := id; idtype := nil;
  170. X          extern := false; pflev := level; genlabel(lbname);
  171. X          pfdeckind := declared; pfkind := actual; pfname := lbname;
  172. X          if fsy = procsy then klass := proc
  173. X          else klass := func
  174. X        end;
  175. X          enterid(lcp)
  176. X        end
  177. X      else
  178. X        begin lcp1 := lcp^.next;
  179. X          while lcp1 <> nil do
  180. X        begin
  181. X          with lcp1^ do
  182. X            if klass = vars then
  183. X              if idtype <> nil then
  184. X            begin lcm := vaddr + idtype^.size;
  185. X              if lcm > lc then lc := lcm
  186. X            end;
  187. X          lcp1 := lcp1^.next
  188. X        end
  189. X        end;
  190. X      insymbol
  191. X    end
  192. X      else
  193. X    begin error(2); lcp := ufctptr end;
  194. X      oldlev := level; oldtop := top;
  195. X      if level < maxlevel then level := level + 1 else error(251);
  196. X      if top < displimit then
  197. X    begin top := top + 1;
  198. X      with display[top] do
  199. X        begin
  200. X          if forw then fname := lcp^.next
  201. X          else fname := nil;
  202. X          flabel := nil;
  203. X          occur := blck
  204. X        end
  205. X    end
  206. X      else error(250);
  207. X      if fsy = procsy then
  208. X    begin parameterlist([semicolon],lcp1);
  209. X      if not forw then lcp^.next := lcp1
  210. X    end
  211. X      else
  212. X    begin parameterlist([semicolon,colon],lcp1);
  213. X      if not forw then lcp^.next := lcp1;
  214. X      if sy = colon then
  215. X        begin insymbol;
  216. X          if sy = ident then
  217. X        begin if forw then error(122);
  218. X          searchid([types],lcp1);
  219. X          lsp := lcp1^.idtype;
  220. X          lcp^.idtype := lsp;
  221. X          if lsp <> nil then
  222. X            if not (lsp^.form in [scalar,subrange,pointer]) then
  223. X              begin error(120); lcp^.idtype := nil end;
  224. X          insymbol
  225. X        end
  226. X          else begin error(2); skip(fsys + [semicolon]) end
  227. X        end
  228. X      else
  229. X        if not forw then error(123)
  230. X    end;
  231. X      if sy = semicolon then insymbol else error(14);
  232. X      if sy = forwardsy then
  233. X    begin
  234. X      if forw then error(161)
  235. X      else lcp^.forwdecl := true;
  236. X      insymbol;
  237. X      if sy = semicolon then insymbol else error(14);
  238. X      if not (sy in fsys) then
  239. X        begin error(6); skip(fsys) end
  240. X    end
  241. X      else
  242. X    begin lcp^.forwdecl := false; mark(markp);
  243. X      repeat block(fsys,semicolon,lcp);
  244. X        if sy = semicolon then
  245. X          begin if prtables then printtables(false); insymbol;
  246. X        if not (sy in [beginsy,procsy,funcsy]) then
  247. X          begin error(6); skip(fsys) end
  248. X          end
  249. X        else error(14)
  250. X      until (sy in [beginsy,procsy,funcsy]) or eof(input);
  251. X      release(markp); (* return local entries on runtime heap *)
  252. X    end;
  253. X      level := oldlev; top := oldtop; lc := llc;
  254. X    end (*procdeclaration*) ;
  255. X
  256. X    procedure body(fsys: setofsys);
  257. X      const cstoccmax=65; cixmax=1000;
  258. X      type oprange = 0..63;
  259. X      var
  260. X      llcp:ctp; saveid:alpha;
  261. X      cstptr: array [1..cstoccmax] of csp;
  262. X      cstptrix: 0..cstoccmax;
  263. X      (*allows referencing of noninteger constants by an index
  264. X       (instead of a pointer), which can be stored in the p2-field
  265. X       of the instruction record until writeout.
  266. X       --> procedure load, procedure writeout*)
  267. X      entname, segsize: integer;
  268. X      stacktop, topnew, topmax: integer;
  269. X      lcmax,llc1: addrrange; lcp: ctp;
  270. X      llp: lbp;
  271. X
  272. X
  273. X      procedure mes(i: integer);
  274. X      begin topnew := topnew + cdx[i]*maxstack;
  275. X    if topnew > topmax then topmax := topnew
  276. X      end;
  277. X
  278. X      procedure putic;
  279. X      begin if ic mod 10 = 0 then writeln(prr,'i',ic:5) end;
  280. X
  281. X      procedure gen0(fop: oprange);
  282. X      begin
  283. X    if prcode then begin putic; writeln(prr,mn[fop]:4) end;
  284. X    ic := ic + 1; mes(fop)
  285. X      end (*gen0*) ;
  286. X
  287. X      procedure gen1(fop: oprange; fp2: integer);
  288. X    var k: integer;
  289. X      begin
  290. X    if prcode then
  291. X      begin putic; write(prr,mn[fop]:4);
  292. X        if fop = 30 then
  293. X          begin writeln(prr,sna[fp2]:12);
  294. X        topnew := topnew + pdx[fp2]*maxstack;
  295. X        if topnew > topmax then topmax := topnew
  296. X          end
  297. X        else
  298. X          begin
  299. X        if fop = 38 then
  300. X           begin write(prr,'''');
  301. X             with cstptr[fp2]^ do
  302. X             begin
  303. X               for k := 1 to slgth do write(prr,sval[k]:1);
  304. X               for k := slgth+1 to strglgth do write(prr,' ');
  305. X             end;
  306. X             writeln(prr,'''')
  307. X           end
  308. X        else if fop = 42 then writeln(prr,chr(fp2))
  309. X             else writeln(prr,fp2:12);
  310. X        mes(fop)
  311. X          end
  312. X      end;
  313. X    ic := ic + 1
  314. X      end (*gen1*) ;
  315. X
  316. X      procedure gen2(fop: oprange; fp1,fp2: integer);
  317. X    var k : integer;
  318. X      begin
  319. X    if prcode then
  320. X      begin putic; write(prr,mn[fop]:4);
  321. X        case fop of
  322. X          45,50,54,56:
  323. X        writeln(prr,' ',fp1:3,fp2:8);
  324. X          47,48,49,52,53,55:
  325. X        begin write(prr,chr(fp1));
  326. X          if chr(fp1) = 'm' then write(prr,fp2:11);
  327. X          writeln(prr)
  328. X        end;
  329. X          51:
  330. X        case fp1 of
  331. X          1: writeln(prr,'i ',fp2);
  332. X          2: begin write(prr,'r ');
  333. X               with cstptr[fp2]^ do
  334. X             for k := 1 to strglgth do write(prr,rval[k]);
  335. X               writeln(prr)
  336. X             end;
  337. X          3: writeln(prr,'b ',fp2);
  338. X          4: writeln(prr,'n');
  339. X          6: writeln(prr,'c ''':3,chr(fp2),'''');
  340. X          5: begin write(prr,'(');
  341. X               with cstptr[fp2]^ do
  342. X             for k := setlow to sethigh do
  343. X               if k in pval then write(prr,k:3);
  344. X               writeln(prr,')')
  345. X             end
  346. X        end
  347. X        end;
  348. X      end;
  349. X    ic := ic + 1; mes(fop)
  350. X      end (*gen2*) ;
  351. X
  352. X      procedure gentypindicator(fsp: stp);
  353. X      begin
  354. X    if fsp<>nil then
  355. X      with fsp^ do
  356. X        case form of
  357. X         scalar: if fsp=intptr then write(prr,'i')
  358. X             else
  359. X               if fsp=boolptr then write(prr,'b')
  360. X               else
  361. X             if fsp=charptr then write(prr,'c')
  362. X             else
  363. X               if scalkind = declared then write(prr,'i')
  364. X               else write(prr,'r');
  365. X         subrange: gentypindicator(rangetype);
  366. X         pointer:  write(prr,'a');
  367. X         power:    write(prr,'s');
  368. X         records,arrays: write(prr,'m');
  369. X         files,tagfld,variant: error(500)
  370. X        end
  371. X      end (*typindicator*);
  372. X
  373. X      procedure gen0t(fop: oprange; fsp: stp);
  374. X      begin
  375. X    if prcode then
  376. X      begin putic;
  377. X        write(prr,mn[fop]:4);
  378. X        gentypindicator(fsp);
  379. X        writeln(prr);
  380. X      end;
  381. X    ic := ic + 1; mes(fop)
  382. X      end (*gen0t*);
  383. X
  384. X      procedure gen1t(fop: oprange; fp2: integer; fsp: stp);
  385. X      begin
  386. X    if prcode then
  387. X      begin putic;
  388. X        write(prr,mn[fop]:4);
  389. X        gentypindicator(fsp);
  390. X        writeln(prr,fp2:11)
  391. X      end;
  392. X    ic := ic + 1; mes(fop)
  393. X      end (*gen1t*);
  394. X
  395. X      procedure gen2t(fop: oprange; fp1,fp2: integer; fsp: stp);
  396. X      begin
  397. X    if prcode then
  398. X      begin putic;
  399. X        write(prr,mn[fop]: 4);
  400. X        gentypindicator(fsp);
  401. X        writeln(prr,fp1:3+5*ord(abs(fp1)>99),fp2:8);
  402. X      end;
  403. X    ic := ic + 1; mes(fop)
  404. X      end (*gen2t*);
  405. X
  406. X      procedure load;
  407. X      begin
  408. X    with gattr do
  409. X      if typtr <> nil then
  410. X        begin
  411. X          case kind of
  412. X        cst:   if (typtr^.form = scalar) and (typtr <> realptr) then
  413. X             if typtr = boolptr then gen2(51(*ldc*),3,cval.ival)
  414. X             else
  415. X               if typtr=charptr then
  416. X                 gen2(51(*ldc*),6,cval.ival)
  417. X               else gen2(51(*ldc*),1,cval.ival)
  418. X               else
  419. X             if typtr = nilptr then gen2(51(*ldc*),4,0)
  420. X             else
  421. X               if cstptrix >= cstoccmax then error(254)
  422. X               else
  423. X                 begin cstptrix := cstptrix + 1;
  424. X                   cstptr[cstptrix] := cval.valp;
  425. X                   if typtr = realptr then
  426. X                 gen2(51(*ldc*),2,cstptrix)
  427. X                   else
  428. X                 gen2(51(*ldc*),5,cstptrix)
  429. X                 end;
  430. X        varbl: case access of
  431. X             drct:   if vlevel<=1 then
  432. X                   gen1t(39(*ldo*),dplmt,typtr)
  433. X                 else gen2t(54(*lod*),level-vlevel,dplmt,typtr);
  434. X             indrct: gen1t(35(*ind*),idplmt,typtr);
  435. X             inxd:   error(400)
  436. X               end;
  437. X        expr:
  438. X          end;
  439. X          kind := expr
  440. X        end
  441. X      end (*load*) ;
  442. X
  443. X      procedure store(var fattr: attr);
  444. X      begin
  445. X    with fattr do
  446. X      if typtr <> nil then
  447. X        case access of
  448. X          drct:   if vlevel <= 1 then gen1t(43(*sro*),dplmt,typtr)
  449. X              else gen2t(56(*str*),level-vlevel,dplmt,typtr);
  450. X          indrct: if idplmt <> 0 then error(400)
  451. X              else gen0t(26(*sto*),typtr);
  452. X          inxd:   error(400)
  453. X        end
  454. X      end (*store*) ;
  455. X
  456. X      procedure loadaddress;
  457. X      begin
  458. X    with gattr do
  459. X      if typtr <> nil then
  460. X        begin
  461. X          case kind of
  462. X        cst:   if string(typtr) then
  463. X             if cstptrix >= cstoccmax then error(254)
  464. X             else
  465. X               begin cstptrix := cstptrix + 1;
  466. X                 cstptr[cstptrix] := cval.valp;
  467. X                 gen1(38(*lca*),cstptrix)
  468. X               end
  469. X               else error(400);
  470. X        varbl: case access of
  471. X             drct:   if vlevel <= 1 then gen1(37(*lao*),dplmt)
  472. X                 else gen2(50(*lda*),level-vlevel,dplmt);
  473. X             indrct: if idplmt <> 0 then
  474. X                   gen1t(34(*inc*),idplmt,nilptr);
  475. X             inxd:   error(400)
  476. X               end;
  477. X        expr:  error(400)
  478. X          end;
  479. X          kind := varbl; access := indrct; idplmt := 0
  480. X        end
  481. X      end (*loadaddress*) ;
  482. X
  483. X
  484. X      procedure genfjp(faddr: integer);
  485. X      begin load;
  486. X    if gattr.typtr <> nil then
  487. X      if gattr.typtr <> boolptr then error(144);
  488. X    if prcode then begin putic; writeln(prr,mn[33]:4,' l':8,faddr:4) end;
  489. X    ic := ic + 1; mes(33)
  490. X      end (*genfjp*) ;
  491. X
  492. X      procedure genujpxjp(fop: oprange; fp2: integer);
  493. X      begin
  494. X       if prcode then
  495. X      begin putic; writeln(prr, mn[fop]:4, ' l':8,fp2:4) end;
  496. X    ic := ic + 1; mes(fop)
  497. X      end (*genujpxjp*);
  498. X
  499. X
  500. X      procedure gencupent(fop: oprange; fp1,fp2: integer);
  501. X      begin
  502. X    if prcode then
  503. X      begin putic;
  504. X        writeln(prr,mn[fop]:4,fp1:4,'l':4,fp2:4)
  505. X      end;
  506. X    ic := ic + 1; mes(fop)
  507. X      end;
  508. X
  509. X
  510. X      procedure checkbnds(fsp: stp);
  511. X    var lmin,lmax: integer;
  512. X      begin
  513. X    if fsp <> nil then
  514. X      if fsp <> intptr then
  515. X        if fsp <> realptr then
  516. X          if fsp^.form <= subrange then
  517. X        begin
  518. X          getbounds(fsp,lmin,lmax);
  519. X          gen2t(45(*chk*),lmin,lmax,fsp)
  520. X        end
  521. X      end (*checkbnds*);
  522. X
  523. X
  524. X      procedure putlabel(labname: integer);
  525. X      begin if prcode then writeln(prr, 'l', labname:4)
  526. X      end (*putlabel*);
  527. X
  528. X      procedure statement(fsys: setofsys);
  529. X    label 1;
  530. X    var lcp: ctp; llp: lbp;
  531. X
  532. X    procedure expression(fsys: setofsys); forward;
  533. X
  534. X    procedure selector(fsys: setofsys; fcp: ctp);
  535. X    var lattr: attr; lcp: ctp; lsize: addrrange; lmin,lmax: integer;
  536. X    begin
  537. X      with fcp^, gattr do
  538. X        begin typtr := idtype; kind := varbl;
  539. X          case klass of
  540. X        vars:
  541. X          if vkind = actual then
  542. X            begin access := drct; vlevel := vlev;
  543. X              dplmt := vaddr
  544. X            end
  545. X          else
  546. X            begin gen2t(54(*lod*),level-vlev,vaddr,nilptr);
  547. X              access := indrct; idplmt := 0
  548. X            end;
  549. X        field:
  550. X          with display[disx] do
  551. X            if occur = crec then
  552. X              begin access := drct; vlevel := clev;
  553. X            dplmt := cdspl + fldaddr
  554. X              end
  555. X            else
  556. X              begin
  557. X            if level = 1 then gen1t(39(*ldo*),vdspl,nilptr)
  558. X            else gen2t(54(*lod*),0,vdspl,nilptr);
  559. X            access := indrct; idplmt := fldaddr
  560. X              end;
  561. X        func:
  562. X          if pfdeckind = standard then
  563. X            begin error(150); typtr := nil end
  564. X          else
  565. X            begin
  566. X              if pfkind = formal then error(151)
  567. X              else
  568. X            if (pflev+1<>level)or(fprocp<>fcp) then error(177);
  569. X            begin access := drct; vlevel := pflev + 1;
  570. X              dplmt := 0   (*impl. relat. addr. of fct. result*)
  571. X            end
  572. X            end
  573. X          end (*case*)
  574. X        end (*with*);
  575. X      if not (sy in selectsys + fsys) then
  576. X        begin error(59); skip(selectsys + fsys) end;
  577. X      while sy in selectsys do
  578. X        begin
  579. X    (*[*) if sy = lbrack then
  580. X        begin
  581. X          repeat lattr := gattr;
  582. X            with lattr do
  583. X              if typtr <> nil then
  584. X            if typtr^.form <> arrays then
  585. X              begin error(138); typtr := nil end;
  586. X            loadaddress;
  587. X            insymbol; expression(fsys + [comma,rbrack]);
  588. X            load;
  589. X            if gattr.typtr <> nil then
  590. X              if gattr.typtr^.form<>scalar then error(113)
  591. X              else if not comptypes(gattr.typtr,intptr) then
  592. X                 gen0t(58(*ord*),gattr.typtr);
  593. X            if lattr.typtr <> nil then
  594. X              with lattr.typtr^ do
  595. X            begin
  596. X              if comptypes(inxtype,gattr.typtr) then
  597. X                begin
  598. X                  if inxtype <> nil then
  599. X                begin getbounds(inxtype,lmin,lmax);
  600. X                  if debug then
  601. X                    gen2t(45(*chk*),lmin,lmax,intptr);
  602. X                  if lmin>0 then gen1t(31(*dec*),lmin,intptr)
  603. X                  else if lmin<0 then
  604. X                    gen1t(34(*inc*),-lmin,intptr);
  605. X                  (*or simply gen1(31,lmin)*)
  606. X                end
  607. X                end
  608. X              else error(139);
  609. X              with gattr do
  610. X                begin typtr := aeltype; kind := varbl;
  611. X                  access := indrct; idplmt := 0
  612. X                end;
  613. X              if gattr.typtr <> nil then
  614. X                begin
  615. X                  lsize := gattr.typtr^.size;
  616. X                  align(gattr.typtr,lsize);
  617. X                  gen1(36(*ixa*),lsize)
  618. X                end
  619. X            end
  620. X          until sy <> comma;
  621. X          if sy = rbrack then insymbol else error(12)
  622. X        end (*if sy = lbrack*)
  623. X          else
  624. X    (*.*)   if sy = period then
  625. X          begin
  626. X            with gattr do
  627. X              begin
  628. X            if typtr <> nil then
  629. X              if typtr^.form <> records then
  630. X                begin error(140); typtr := nil end;
  631. X            insymbol;
  632. X            if sy = ident then
  633. X              begin
  634. X                if typtr <> nil then
  635. X                  begin searchsection(typtr^.fstfld,lcp);
  636. X                if lcp = nil then
  637. X                  begin error(152); typtr := nil end
  638. X                else
  639. X                  with lcp^ do
  640. X                    begin typtr := idtype;
  641. X                      case access of
  642. X                    drct:   dplmt := dplmt + fldaddr;
  643. X                    indrct: idplmt := idplmt + fldaddr;
  644. X                    inxd:   error(400)
  645. X                      end
  646. X                    end
  647. X                  end;
  648. X                insymbol
  649. X              end (*sy = ident*)
  650. X            else error(2)
  651. X              end (*with gattr*)
  652. X          end (*if sy = period*)
  653. X        else
  654. X    (*^*)     begin
  655. X            if gattr.typtr <> nil then
  656. X              with gattr,typtr^ do
  657. X            if form = pointer then
  658. X              begin load; typtr := eltype;
  659. X                if debug then gen2t(45(*chk*),1,maxaddr,nilptr);
  660. X                with gattr do
  661. X                  begin kind := varbl; access := indrct;
  662. X                idplmt := 0
  663. X                  end
  664. X              end
  665. X            else
  666. X              if form = files then typtr := filtype
  667. X              else error(141);
  668. X            insymbol
  669. X          end;
  670. X          if not (sy in fsys + selectsys) then
  671. X        begin error(6); skip(fsys + selectsys) end
  672. X        end (*while*)
  673. X    end (*selector*) ;
  674. X
  675. X    procedure call(fsys: setofsys; fcp: ctp);
  676. X      var lkey: 1..15;
  677. X
  678. X      procedure variable(fsys: setofsys);
  679. X        var lcp: ctp;
  680. X      begin
  681. X        if sy = ident then
  682. X          begin searchid([vars,field],lcp); insymbol end
  683. X        else begin error(2); lcp := uvarptr end;
  684. X        selector(fsys,lcp)
  685. X      end (*variable*) ;
  686. X
  687. X      procedure getputresetrewrite;
  688. X      begin variable(fsys + [rparent]); loadaddress;
  689. X        if gattr.typtr <> nil then
  690. X          if gattr.typtr^.form <> files then error(116);
  691. X        if lkey <= 2 then gen1(30(*csp*),lkey(*get,put*))
  692. X        else error(399)
  693. X      end (*getputresetrewrite*) ;
  694. X
  695. X      procedure read;
  696. X        var llev:levrange; laddr:addrrange;
  697. X        lsp : stp;
  698. X      begin
  699. X        llev := 1; laddr := lcaftermarkstack;
  700. X        if sy = lparent then
  701. X          begin insymbol;
  702. X        variable(fsys + [comma,rparent]);
  703. X        lsp := gattr.typtr; test := false;
  704. X        if lsp <> nil then
  705. X          if lsp^.form = files then
  706. X            with gattr, lsp^ do
  707. X              begin
  708. X            if filtype = charptr then
  709. X              begin llev := vlevel; laddr := dplmt end
  710. X            else error(399);
  711. X            if sy = rparent then
  712. X              begin if lkey = 5 then error(116);
  713. X                test := true
  714. X              end
  715. X            else
  716. X              if sy <> comma then
  717. X                begin error(116); skip(fsys + [comma,rparent]) end;
  718. X            if sy = comma then
  719. X              begin insymbol; variable(fsys + [comma,rparent])
  720. X              end
  721. X            else test := true
  722. X              end;
  723. X           if not test then
  724. X        repeat loadaddress;
  725. X          gen2(50(*lda*),level-llev,laddr);
  726. X          if gattr.typtr <> nil then
  727. X            if gattr.typtr^.form <= subrange then
  728. X              if comptypes(intptr,gattr.typtr) then
  729. X            gen1(30(*csp*),3(*rdi*))
  730. X              else
  731. X            if comptypes(realptr,gattr.typtr) then
  732. X              gen1(30(*csp*),4(*rdr*))
  733. X            else
  734. X              if comptypes(charptr,gattr.typtr) then
  735. X                gen1(30(*csp*),5(*rdc*))
  736. X              else error(399)
  737. X            else error(116);
  738. X          test := sy <> comma;
  739. X          if not test then
  740. X            begin insymbol; variable(fsys + [comma,rparent])
  741. X            end
  742. X        until test;
  743. X        if sy = rparent then insymbol else error(4)
  744. X          end
  745. X        else if lkey = 5 then error(116);
  746. X        if lkey = 11 then
  747. X          begin gen2(50(*lda*),level-llev,laddr);
  748. X        gen1(30(*csp*),21(*rln*))
  749. X          end
  750. X      end (*read*) ;
  751. X
  752. X      procedure write;
  753. X        var lsp: stp; default : boolean; llkey: 1..15;
  754. X        llev:levrange; laddr,len:addrrange;
  755. X      begin llkey := lkey;
  756. X        llev := 1; laddr := lcaftermarkstack + charmax;
  757. X        if sy = lparent then
  758. X        begin insymbol;
  759. X        expression(fsys + [comma,colon,rparent]);
  760. X        lsp := gattr.typtr; test := false;
  761. X        if lsp <> nil then
  762. X          if lsp^.form = files then
  763. X        with gattr, lsp^ do
  764. X          begin
  765. X            if filtype = charptr then
  766. X              begin llev := vlevel; laddr := dplmt end
  767. X            else error(399);
  768. X            if sy = rparent then
  769. X              begin if llkey = 6 then error(116);
  770. X            test := true
  771. X              end
  772. X            else
  773. X              if sy <> comma then
  774. X            begin error(116); skip(fsys+[comma,rparent]) end;
  775. X            if sy = comma then
  776. X              begin insymbol; expression(fsys+[comma,colon,rparent])
  777. X              end
  778. X            else test := true
  779. X          end;
  780. X       if not test then
  781. X        repeat
  782. X          lsp := gattr.typtr;
  783. X          if lsp <> nil then
  784. X        if lsp^.form <= subrange then load else loadaddress;
  785. X          if sy = colon then
  786. X        begin insymbol; expression(fsys + [comma,colon,rparent]);
  787. X          if gattr.typtr <> nil then
  788. X            if gattr.typtr <> intptr then error(116);
  789. X          load; default := false
  790. X        end
  791. X          else default := true;
  792. X          if sy = colon then
  793. X        begin insymbol; expression(fsys + [comma,rparent]);
  794. X          if gattr.typtr <> nil then
  795. X            if gattr.typtr <> intptr then error(116);
  796. X          if lsp <> realptr then error(124);
  797. X          load; error(399);
  798. X        end
  799. X          else
  800. X        if lsp = intptr then
  801. X          begin if default then gen2(51(*ldc*),1,10);
  802. X            gen2(50(*lda*),level-llev,laddr);
  803. X            gen1(30(*csp*),6(*wri*))
  804. X          end
  805. X        else
  806. X          if lsp = realptr then
  807. X            begin if default then gen2(51(*ldc*),1,20);
  808. X              gen2(50(*lda*),level-llev,laddr);
  809. X              gen1(30(*csp*),8(*wrr*))
  810. X            end
  811. X          else
  812. X            if lsp = charptr then
  813. X              begin if default then gen2(51(*ldc*),1,1);
  814. X            gen2(50(*lda*),level-llev,laddr);
  815. X            gen1(30(*csp*),9(*wrc*))
  816. X              end
  817. X            else
  818. X              if lsp <> nil then
  819. X            begin
  820. X              if lsp^.form = scalar then error(399)
  821. X              else
  822. X                if string(lsp) then
  823. X                  begin len := lsp^.size div charmax;
  824. X                if default then
  825. X                      gen2(51(*ldc*),1,len);
  826. X                gen2(51(*ldc*),1,len);
  827. X                gen2(50(*lda*),level-llev,laddr);
  828. X                gen1(30(*csp*),10(*wrs*))
  829. X                  end
  830. X                else error(116)
  831. X            end;
  832. X          test := sy <> comma;
  833. X          if not test then
  834. X        begin insymbol; expression(fsys + [comma,colon,rparent])
  835. X        end
  836. X        until test;
  837. X        if sy = rparent then insymbol else error(4)
  838. X        end
  839. X          else if lkey = 6 then error(116);
  840. X        if llkey = 12 then (*writeln*)
  841. X          begin gen2(50(*lda*),level-llev,laddr);
  842. X        gen1(30(*csp*),22(*wln*))
  843. X          end
  844. X      end (*write*) ;
  845. X
  846. X      procedure pack;
  847. X        var lsp,lsp1: stp;
  848. X      begin error(399); variable(fsys + [comma,rparent]);
  849. X        lsp := nil; lsp1 := nil;
  850. X        if gattr.typtr <> nil then
  851. X          with gattr.typtr^ do
  852. X        if form = arrays then
  853. X          begin lsp := inxtype; lsp1 := aeltype end
  854. X        else error(116);
  855. X        if sy = comma then insymbol else error(20);
  856. X        expression(fsys + [comma,rparent]);
  857. X        if gattr.typtr <> nil then
  858. X          if gattr.typtr^.form <> scalar then error(116)
  859. X          else
  860. X        if not comptypes(lsp,gattr.typtr) then error(116);
  861. X        if sy = comma then insymbol else error(20);
  862. X        variable(fsys + [rparent]);
  863. X        if gattr.typtr <> nil then
  864. X          with gattr.typtr^ do
  865. X        if form = arrays then
  866. X          begin
  867. X            if not comptypes(aeltype,lsp1)
  868. X              or not comptypes(inxtype,lsp) then
  869. X              error(116)
  870. X          end
  871. X        else error(116)
  872. X      end (*pack*) ;
  873. X
  874. X      procedure unpack;
  875. X        var lsp,lsp1: stp;
  876. X      begin error(399); variable(fsys + [comma,rparent]);
  877. X        lsp := nil; lsp1 := nil;
  878. X        if gattr.typtr <> nil then
  879. X          with gattr.typtr^ do
  880. X        if form = arrays then
  881. X          begin lsp := inxtype; lsp1 := aeltype end
  882. X        else error(116);
  883. X        if sy = comma then insymbol else error(20);
  884. X        variable(fsys + [comma,rparent]);
  885. X        if gattr.typtr <> nil then
  886. X          with gattr.typtr^ do
  887. X        if form = arrays then
  888. X          begin
  889. X            if not comptypes(aeltype,lsp1)
  890. X              or not comptypes(inxtype,lsp) then
  891. X              error(116)
  892. X          end
  893. X        else error(116);
  894. X        if sy = comma then insymbol else error(20);
  895. X        expression(fsys + [rparent]);
  896. X        if gattr.typtr <> nil then
  897. X          if gattr.typtr^.form <> scalar then error(116)
  898. X          else
  899. X        if not comptypes(lsp,gattr.typtr) then error(116);
  900. X      end (*unpack*) ;
  901. X
  902. X      procedure new;
  903. X        label 1;
  904. X        var lsp,lsp1: stp; varts: integer;
  905. X        lsize: addrrange; lval: valu;
  906. X      begin variable(fsys + [comma,rparent]); loadaddress;
  907. X        lsp := nil; varts := 0; lsize := 0;
  908. X        if gattr.typtr <> nil then
  909. X          with gattr.typtr^ do
  910. X        if form = pointer then
  911. X          begin
  912. X            if eltype <> nil then
  913. X              begin lsize := eltype^.size;
  914. X            if eltype^.form = records then lsp := eltype^.recvar
  915. X              end
  916. X          end
  917. X        else error(116);
  918. X        while sy = comma do
  919. X          begin insymbol;constant(fsys + [comma,rparent],lsp1,lval);
  920. X        varts := varts + 1;
  921. X        (*check to insert here: is constant in tagfieldtype range*)
  922. X        if lsp = nil then error(158)
  923. X        else
  924. X          if lsp^.form <> tagfld then error(162)
  925. X          else
  926. X            if lsp^.tagfieldp <> nil then
  927. X              if string(lsp1) or (lsp1 = realptr) then error(159)
  928. X              else
  929. X            if comptypes(lsp^.tagfieldp^.idtype,lsp1) then
  930. X              begin
  931. X                lsp1 := lsp^.fstvar;
  932. X                while lsp1 <> nil do
  933. X                  with lsp1^ do
  934. X                if varval.ival = lval.ival then
  935. X                  begin lsize := size; lsp := subvar;
  936. X                    goto 1
  937. X                  end
  938. X                else lsp1 := nxtvar;
  939. X                lsize := lsp^.size; lsp := nil;
  940. X              end
  941. X            else error(116);
  942. X      1:  end (*while*) ;
  943. X        gen2(51(*ldc*),1,lsize);
  944. X        gen1(30(*csp*),12(*new*));
  945. X      end (*new*) ;
  946. X
  947. X      procedure mark;
  948. X      begin variable(fsys+[rparent]);
  949. X         if gattr.typtr <> nil then
  950. X           if gattr.typtr^.form = pointer then
  951. X         begin loadaddress; gen1(30(*csp*),23(*sav*)) end
  952. X           else error(116)
  953. X      end(*mark*);
  954. X
  955. X      procedure release;
  956. X      begin variable(fsys+[rparent]);
  957. X        if gattr.typtr <> nil then
  958. X           if gattr.typtr^.form = pointer then
  959. X              begin load; gen1(30(*csp*),13(*rst*)) end
  960. X           else error(116)
  961. X      end (*release*);
  962. X
  963. X
  964. X
  965. X      procedure abs;
  966. X      begin
  967. X        if gattr.typtr <> nil then
  968. X          if gattr.typtr = intptr then gen0(0(*abi*))
  969. X          else
  970. X        if gattr.typtr = realptr then gen0(1(*abr*))
  971. X        else begin error(125); gattr.typtr := intptr end
  972. X      end (*abs*) ;
  973. X
  974. X      procedure sqr;
  975. X      begin
  976. X        if gattr.typtr <> nil then
  977. X          if gattr.typtr = intptr then gen0(24(*sqi*))
  978. X          else
  979. X        if gattr.typtr = realptr then gen0(25(*sqr*))
  980. X        else begin error(125); gattr.typtr := intptr end
  981. X      end (*sqr*) ;
  982. X
  983. X      procedure trunc;
  984. X      begin
  985. X        if gattr.typtr <> nil then
  986. X          if gattr.typtr <> realptr then error(125);
  987. X        gen0(27(*trc*));
  988. X        gattr.typtr := intptr
  989. X      end (*trunc*) ;
  990. X
  991. X      procedure odd;
  992. X      begin
  993. X        if gattr.typtr <> nil then
  994. X          if gattr.typtr <> intptr then error(125);
  995. X        gen0(20(*odd*));
  996. X        gattr.typtr := boolptr
  997. X      end (*odd*) ;
  998. X
  999. X      procedure ord;
  1000. X      begin
  1001. X        if gattr.typtr <> nil then
  1002. X          if gattr.typtr^.form >= power then error(125);
  1003. X        gen0t(58(*ord*),gattr.typtr);
  1004. X        gattr.typtr := intptr
  1005. X      end (*ord*) ;
  1006. X
  1007. X      procedure chr;
  1008. X      begin
  1009. X        if gattr.typtr <> nil then
  1010. X          if gattr.typtr <> intptr then error(125);
  1011. X        gen0(59(*chr*));
  1012. X        gattr.typtr := charptr
  1013. X      end (*chr*) ;
  1014. X
  1015. X      procedure predsucc;
  1016. X      begin
  1017. X        if gattr.typtr <> nil then
  1018. X          if gattr.typtr^.form <> scalar then error(125);
  1019. X        if lkey = 7 then gen1t(31(*dec*),1,gattr.typtr)
  1020. X        else gen1t(34(*inc*),1,gattr.typtr)
  1021. X      end (*predsucc*) ;
  1022. X
  1023. X      procedure eof;
  1024. X      begin
  1025. X        if sy = lparent then
  1026. X          begin insymbol; variable(fsys + [rparent]);
  1027. X        if sy = rparent then insymbol else error(4)
  1028. X          end
  1029. X        else
  1030. X          with gattr do
  1031. X        begin typtr := textptr; kind := varbl; access := drct;
  1032. X          vlevel := 1; dplmt := lcaftermarkstack
  1033. X        end;
  1034. X        loadaddress;
  1035. X        if gattr.typtr <> nil then
  1036. X          if gattr.typtr^.form <> files then error(125);
  1037. X        if lkey = 9 then gen0(8(*eof*)) else gen1(30(*csp*),14(*eln*));
  1038. X          gattr.typtr := boolptr
  1039. X      end (*eof*) ;
  1040. X
  1041. X
  1042. X
  1043. X      procedure callnonstandard;
  1044. X        var nxt,lcp: ctp; lsp: stp; lkind: idkind; lb: boolean;
  1045. X        locpar, llc: addrrange;
  1046. X      begin locpar := 0;
  1047. X        with fcp^ do
  1048. X          begin nxt := next; lkind := pfkind;
  1049. X        if not extern then gen1(41(*mst*),level-pflev)
  1050. X          end;
  1051. X        if sy = lparent then
  1052. X          begin llc := lc;
  1053. X        repeat lb := false; (*decide whether proc/func must be passed*)
  1054. X          if lkind = actual then
  1055. X            begin
  1056. X              if nxt = nil then error(126)
  1057. X              else lb := nxt^.klass in [proc,func]
  1058. X            end else error(399);
  1059. X          (*For formal proc/func, lb is false and expression
  1060. X           will be called, which will always interpret a proc/func id
  1061. X           at its beginning as a call rather than a parameter passing.
  1062. X           In this implementation, parameter procedures/functions
  1063. X           are therefore not allowed to have procedure/function
  1064. X           parameters*)
  1065. X          insymbol;
  1066. X          if lb then   (*pass function or procedure*)
  1067. X            begin error(399);
  1068. X              if sy <> ident then
  1069. X            begin error(2); skip(fsys + [comma,rparent]) end
  1070. X              else
  1071. X            begin
  1072. X              if nxt^.klass = proc then searchid([proc],lcp)
  1073. X              else
  1074. X                begin searchid([func],lcp);
  1075. X                  if not comptypes(lcp^.idtype,nxt^.idtype) then
  1076. X                error(128)
  1077. X                end;
  1078. X              insymbol;
  1079. X              if not (sy in fsys + [comma,rparent]) then
  1080. X                begin error(6); skip(fsys + [comma,rparent]) end
  1081. X            end
  1082. X            end (*if lb*)
  1083. X          else
  1084. X            begin expression(fsys + [comma,rparent]);
  1085. X              if gattr.typtr <> nil then
  1086. X            if lkind = actual then
  1087. X              begin
  1088. X                if nxt <> nil then
  1089. X                  begin lsp := nxt^.idtype;
  1090. X                if lsp <> nil then
  1091. X                  begin
  1092. X                    if (nxt^.vkind = actual) then
  1093. X                      if lsp^.form <= power then
  1094. X                    begin load;
  1095. X                      if debug then checkbnds(lsp);
  1096. X                      if comptypes(realptr,lsp)
  1097. X                         and (gattr.typtr = intptr) then
  1098. X                        begin gen0(10(*flt*));
  1099. X                          gattr.typtr := realptr
  1100. X                        end;
  1101. X                      locpar := locpar+lsp^.size;
  1102. X                      align(parmptr,locpar);
  1103. X                    end
  1104. X                      else
  1105. X                    begin
  1106. X                      loadaddress;
  1107. X                      locpar := locpar+ptrsize;
  1108. X                      align(parmptr,locpar)
  1109. X                    end
  1110. X                    else
  1111. X                      if gattr.kind = varbl then
  1112. X                    begin loadaddress;
  1113. X                      locpar := locpar+ptrsize;
  1114. X                      align(parmptr,locpar);
  1115. X                    end
  1116. X                      else error(154);
  1117. X                    if not comptypes(lsp,gattr.typtr) then
  1118. X                      error(142)
  1119. X                  end
  1120. X                  end
  1121. X              end
  1122. X              else (*lkind = formal*)
  1123. X            begin (*pass formal param*)
  1124. X            end
  1125. X            end;
  1126. X          if (lkind = actual) and (nxt <> nil) then nxt := nxt^.next
  1127. X        until sy <> comma;
  1128. X        lc := llc;
  1129. X        if sy = rparent then insymbol else error(4)
  1130. X          end (*if lparent*);
  1131. X        if lkind = actual then
  1132. X          begin if nxt <> nil then error(126);
  1133. X        with fcp^ do
  1134. X          begin
  1135. X            if extern then gen1(30(*csp*),pfname)
  1136. X            else gencupent(46(*cup*),locpar,pfname);
  1137. X          end
  1138. X          end;
  1139. X        gattr.typtr := fcp^.idtype
  1140. X      end (*callnonstandard*) ;
  1141. X
  1142. X    begin (*call*)
  1143. X      if fcp^.pfdeckind = standard then
  1144. X        begin lkey := fcp^.key;
  1145. X          if fcp^.klass = proc then
  1146. X           begin
  1147. X        if not(lkey in [5,6,11,12]) then
  1148. X          if sy = lparent then insymbol else error(9);
  1149. X        case lkey of
  1150. X          1,2,
  1151. X          3,4:  getputresetrewrite;
  1152. X          5,11: read;
  1153. X          6,12: write;
  1154. X          7:    pack;
  1155. X          8:    unpack;
  1156. X          9:    new;
  1157. X          10:   release;
  1158. X          13:   mark
  1159. X        end;
  1160. X        if not(lkey in [5,6,11,12]) then
  1161. X          if sy = rparent then insymbol else error(4)
  1162. X           end
  1163. X          else
  1164. X        begin
  1165. X          if lkey <= 8 then
  1166. X            begin
  1167. X              if sy = lparent then insymbol else error(9);
  1168. X              expression(fsys+[rparent]); load
  1169. X            end;
  1170. X          case lkey of
  1171. X            1:    abs;
  1172. X            2:    sqr;
  1173. X            3:    trunc;
  1174. X            4:    odd;
  1175. X            5:    ord;
  1176. X            6:    chr;
  1177. X            7,8:  predsucc;
  1178. X            9,10: eof
  1179. X          end;
  1180. X          if lkey <= 8 then
  1181. X            if sy = rparent then insymbol else error(4)
  1182. X        end;
  1183. X        end (*standard procedures and functions*)
  1184. X      else callnonstandard
  1185. X    end (*call*) ;
  1186. X
  1187. X    procedure expression;
  1188. X      var lattr: attr; lop: operator; typind: char; lsize: addrrange;
  1189. X
  1190. X      procedure simpleexpression(fsys: setofsys);
  1191. X        var lattr: attr; lop: operator; signed: boolean;
  1192. X
  1193. X        procedure term(fsys: setofsys);
  1194. X          var lattr: attr; lop: operator;
  1195. X
  1196. X          procedure factor(fsys: setofsys);
  1197. X        var lcp: ctp; lvp: csp; varpart: boolean;
  1198. X            cstpart: setty; lsp: stp;
  1199. X          begin
  1200. X        if not (sy in facbegsys) then
  1201. X          begin error(58); skip(fsys + facbegsys);
  1202. X            gattr.typtr := nil
  1203. X          end;
  1204. X        while sy in facbegsys do
  1205. X          begin
  1206. X            case sy of
  1207. X          (*id*)    ident:
  1208. X            begin searchid([konst,vars,field,func],lcp);
  1209. X              insymbol;
  1210. X              if lcp^.klass = func then
  1211. X                begin call(fsys,lcp);
  1212. X                  with gattr do
  1213. X                begin kind := expr;
  1214. X                  if typtr <> nil then
  1215. X                    if typtr^.form=subrange then
  1216. X                      typtr := typtr^.rangetype
  1217. X                end
  1218. X                end
  1219. X              else
  1220. X                if lcp^.klass = konst then
  1221. X                  with gattr, lcp^ do
  1222. X                begin typtr := idtype; kind := cst;
  1223. X                  cval := values
  1224. X                end
  1225. X                else
  1226. X                  begin selector(fsys,lcp);
  1227. X                if gattr.typtr<>nil then(*elim.subr.types to*)
  1228. X                  with gattr,typtr^ do(*simplify later tests*)
  1229. X                    if form = subrange then
  1230. X                      typtr := rangetype
  1231. X                  end
  1232. X            end;
  1233. X          (*cst*)   intconst:
  1234. X            begin
  1235. X              with gattr do
  1236. X                begin typtr := intptr; kind := cst;
  1237. X                  cval := val
  1238. X                end;
  1239. X              insymbol
  1240. X            end;
  1241. X              realconst:
  1242. X            begin
  1243. X              with gattr do
  1244. X                begin typtr := realptr; kind := cst;
  1245. X                  cval := val
  1246. X                end;
  1247. X              insymbol
  1248. X            end;
  1249. X              stringconst:
  1250. X            begin
  1251. X              with gattr do
  1252. X                begin
  1253. X                  if lgth = 1 then typtr := charptr
  1254. X                  else
  1255. X                begin new(lsp,arrays);
  1256. X                  with lsp^ do
  1257. X                    begin aeltype := charptr; form:=arrays;
  1258. X                      inxtype := nil; size := lgth*charsize
  1259. X                    end;
  1260. X                  typtr := lsp
  1261. X                end;
  1262. X                  kind := cst; cval := val
  1263. X                end;
  1264. X              insymbol
  1265. X            end;
  1266. X          (* ( *)   lparent:
  1267. X            begin insymbol; expression(fsys + [rparent]);
  1268. X              if sy = rparent then insymbol else error(4)
  1269. X            end;
  1270. X          (*not*)   notsy:
  1271. X            begin insymbol; factor(fsys);
  1272. X              load; gen0(19(*not*));
  1273. X              if gattr.typtr <> nil then
  1274. X                if gattr.typtr <> boolptr then
  1275. X                  begin error(135); gattr.typtr := nil end;
  1276. X            end;
  1277. X          (*[*)     lbrack:
  1278. X            begin insymbol; cstpart := [ ]; varpart := false;
  1279. X              new(lsp,power);
  1280. X              with lsp^ do
  1281. X                begin elset:=nil;size:=setsize;form:=power end;
  1282. X              if sy = rbrack then
  1283. X                begin
  1284. X                  with gattr do
  1285. X                begin typtr := lsp; kind := cst end;
  1286. X                  insymbol
  1287. X                end
  1288. X              else
  1289. X                begin
  1290. X                  repeat expression(fsys + [comma,rbrack]);
  1291. X                if gattr.typtr <> nil then
  1292. X                  if gattr.typtr^.form <> scalar then
  1293. X                    begin error(136); gattr.typtr := nil end
  1294. X                  else
  1295. X                    if comptypes(lsp^.elset,gattr.typtr) then
  1296. X                      begin
  1297. X                    if gattr.kind = cst then
  1298. X                      if (gattr.cval.ival < setlow) or
  1299. X                        (gattr.cval.ival > sethigh) then
  1300. X                        error(304)
  1301. X                      else
  1302. X                        cstpart := cstpart+[gattr.cval.ival]
  1303. X                    else
  1304. X                      begin load;
  1305. X                        if not comptypes(gattr.typtr,intptr)
  1306. X                        then gen0t(58(*ord*),gattr.typtr);
  1307. X                        gen0(23(*sgs*));
  1308. X                        if varpart then gen0(28(*uni*))
  1309. X                        else varpart := true
  1310. X                      end;
  1311. X                    lsp^.elset := gattr.typtr;
  1312. X                    gattr.typtr := lsp
  1313. X                      end
  1314. X                    else error(137);
  1315. X                test := sy <> comma;
  1316. X                if not test then insymbol
  1317. X                  until test;
  1318. X                  if sy = rbrack then insymbol else error(12)
  1319. X                end;
  1320. X              if varpart then
  1321. X                begin
  1322. X                  if cstpart <> [ ] then
  1323. X                begin new(lvp,pset); lvp^.pval := cstpart;
  1324. X                  lvp^.cclass := pset;
  1325. X                  if cstptrix = cstoccmax then error(254)
  1326. X                  else
  1327. X                    begin cstptrix := cstptrix + 1;
  1328. X                      cstptr[cstptrix] := lvp;
  1329. X                      gen2(51(*ldc*),5,cstptrix);
  1330. X                      gen0(28(*uni*)); gattr.kind := expr
  1331. X                    end
  1332. X                end
  1333. X                end
  1334. X              else
  1335. X                begin new(lvp,pset); lvp^.pval := cstpart;
  1336. X                  lvp^.cclass := pset;
  1337. X                  gattr.cval.valp := lvp
  1338. X                end
  1339. X            end
  1340. X            end (*case*) ;
  1341. X            if not (sy in fsys) then
  1342. X              begin error(6); skip(fsys + facbegsys) end
  1343. X          end (*while*)
  1344. X          end (*factor*) ;
  1345. X
  1346. X        begin (*term*)
  1347. X          factor(fsys + [mulop]);
  1348. X          while sy = mulop do
  1349. X        begin load; lattr := gattr; lop := op;
  1350. X          insymbol; factor(fsys + [mulop]); load;
  1351. X          if (lattr.typtr <> nil) and (gattr.typtr <> nil) then
  1352. X            case lop of
  1353. X        (***)     mul:  if (lattr.typtr=intptr)and(gattr.typtr=intptr)
  1354. X                then gen0(15(*mpi*))
  1355. X                else
  1356. X                  begin
  1357. X                if lattr.typtr = intptr then
  1358. X                  begin gen0(9(*flo*));
  1359. X                    lattr.typtr := realptr
  1360. X                  end
  1361. X                else
  1362. X                  if gattr.typtr = intptr then
  1363. X                    begin gen0(10(*flt*));
  1364. X                      gattr.typtr := realptr
  1365. X                    end;
  1366. X                if (lattr.typtr = realptr)
  1367. X                  and(gattr.typtr=realptr)then gen0(16(*mpr*))
  1368. X                else
  1369. X                  if(lattr.typtr^.form=power)
  1370. X                    and comptypes(lattr.typtr,gattr.typtr)then
  1371. X                    gen0(12(*int*))
  1372. X                  else begin error(134); gattr.typtr:=nil end
  1373. X                  end;
  1374. X        (* / *)   rdiv: begin
  1375. X                  if gattr.typtr = intptr then
  1376. X                begin gen0(10(*flt*));
  1377. X                  gattr.typtr := realptr
  1378. X                end;
  1379. X                  if lattr.typtr = intptr then
  1380. X                begin gen0(9(*flo*));
  1381. X                  lattr.typtr := realptr
  1382. X                end;
  1383. X                  if (lattr.typtr = realptr)
  1384. X                and (gattr.typtr=realptr)then gen0(7(*dvr*))
  1385. X                  else begin error(134); gattr.typtr := nil end
  1386. X                end;
  1387. X        (*div*)   idiv: if (lattr.typtr = intptr)
  1388. X                  and (gattr.typtr = intptr) then gen0(6(*dvi*))
  1389. X                else begin error(134); gattr.typtr := nil end;
  1390. X        (*mod*)   imod: if (lattr.typtr = intptr)
  1391. X                  and (gattr.typtr = intptr) then gen0(14(*mod*))
  1392. X                else begin error(134); gattr.typtr := nil end;
  1393. X        (*and*)   andop:if (lattr.typtr = boolptr)
  1394. X                  and (gattr.typtr = boolptr) then gen0(4(*and*))
  1395. X                else begin error(134); gattr.typtr := nil end
  1396. X            end (*case*)
  1397. X          else gattr.typtr := nil
  1398. X        end (*while*)
  1399. X        end (*term*) ;
  1400. X
  1401. X      begin (*simpleexpression*)
  1402. X        signed := false;
  1403. X        if (sy = addop) and (op in [plus,minus]) then
  1404. X          begin signed := op = minus; insymbol end;
  1405. X        term(fsys + [addop]);
  1406. X        if signed then
  1407. X          begin load;
  1408. X        if gattr.typtr = intptr then gen0(17(*ngi*))
  1409. X        else
  1410. X          if gattr.typtr = realptr then gen0(18(*ngr*))
  1411. X          else begin error(134); gattr.typtr := nil end
  1412. X          end;
  1413. X        while sy = addop do
  1414. X          begin load; lattr := gattr; lop := op;
  1415. X        insymbol; term(fsys + [addop]); load;
  1416. X        if (lattr.typtr <> nil) and (gattr.typtr <> nil) then
  1417. X          case lop of
  1418. X      (*+*)       plus:
  1419. X              if (lattr.typtr = intptr)and(gattr.typtr = intptr) then
  1420. X            gen0(2(*adi*))
  1421. X              else
  1422. X            begin
  1423. X              if lattr.typtr = intptr then
  1424. X                begin gen0(9(*flo*));
  1425. X                  lattr.typtr := realptr
  1426. X                end
  1427. X              else
  1428. X                if gattr.typtr = intptr then
  1429. X                  begin gen0(10(*flt*));
  1430. X                gattr.typtr := realptr
  1431. X                  end;
  1432. X              if (lattr.typtr = realptr)and(gattr.typtr = realptr)
  1433. X                then gen0(3(*adr*))
  1434. X              else if(lattr.typtr^.form=power)
  1435. X                 and comptypes(lattr.typtr,gattr.typtr) then
  1436. X                 gen0(28(*uni*))
  1437. X                   else begin error(134); gattr.typtr:=nil end
  1438. X            end;
  1439. X      (*-*)       minus:
  1440. X              if (lattr.typtr = intptr)and(gattr.typtr = intptr) then
  1441. X            gen0(21(*sbi*))
  1442. X              else
  1443. X            begin
  1444. X              if lattr.typtr = intptr then
  1445. X                begin gen0(9(*flo*));
  1446. X                  lattr.typtr := realptr
  1447. X                end
  1448. X              else
  1449. X                if gattr.typtr = intptr then
  1450. X                  begin gen0(10(*flt*));
  1451. X                gattr.typtr := realptr
  1452. X                  end;
  1453. X              if (lattr.typtr = realptr)and(gattr.typtr = realptr)
  1454. X                then gen0(22(*sbr*))
  1455. X              else
  1456. X                if (lattr.typtr^.form = power)
  1457. X                  and comptypes(lattr.typtr,gattr.typtr) then
  1458. X                  gen0(5(*dif*))
  1459. X                else begin error(134); gattr.typtr := nil end
  1460. X            end;
  1461. X      (*or*)      orop:
  1462. X              if(lattr.typtr=boolptr)and(gattr.typtr=boolptr)then
  1463. X            gen0(13(*ior*))
  1464. X              else begin error(134); gattr.typtr := nil end
  1465. X          end (*case*)
  1466. X        else gattr.typtr := nil
  1467. X          end (*while*)
  1468. X      end (*simpleexpression*) ;
  1469. X
  1470. X    begin (*expression*)
  1471. X      simpleexpression(fsys + [relop]);
  1472. X      if sy = relop then
  1473. X        begin
  1474. X          if gattr.typtr <> nil then
  1475. X        if gattr.typtr^.form <= power then load
  1476. X        else loadaddress;
  1477. X          lattr := gattr; lop := op;
  1478. X          if lop = inop then
  1479. X        if not comptypes(gattr.typtr,intptr) then
  1480. X          gen0t(58(*ord*),gattr.typtr);
  1481. X          insymbol; simpleexpression(fsys);
  1482. X          if gattr.typtr <> nil then
  1483. X        if gattr.typtr^.form <= power then load
  1484. X        else loadaddress;
  1485. X          if (lattr.typtr <> nil) and (gattr.typtr <> nil) then
  1486. X        if lop = inop then
  1487. X          if gattr.typtr^.form = power then
  1488. X            if comptypes(lattr.typtr,gattr.typtr^.elset) then
  1489. X              gen0(11(*inn*))
  1490. X            else begin error(129); gattr.typtr := nil end
  1491. X          else begin error(130); gattr.typtr := nil end
  1492. X        else
  1493. X          begin
  1494. X            if lattr.typtr <> gattr.typtr then
  1495. X              if lattr.typtr = intptr then
  1496. X            begin gen0(9(*flo*));
  1497. X              lattr.typtr := realptr
  1498. X            end
  1499. X              else
  1500. X            if gattr.typtr = intptr then
  1501. X              begin gen0(10(*flt*));
  1502. X                gattr.typtr := realptr
  1503. X              end;
  1504. X            if comptypes(lattr.typtr,gattr.typtr) then
  1505. X              begin lsize := lattr.typtr^.size;
  1506. X            case lattr.typtr^.form of
  1507. X              scalar:
  1508. X                if lattr.typtr = realptr then typind := 'r'
  1509. X                else
  1510. X                  if lattr.typtr = boolptr then typind := 'b'
  1511. X                  else
  1512. X                if lattr.typtr = charptr then typind := 'c'
  1513. X                else typind := 'i';
  1514. X              pointer:
  1515. X                begin
  1516. X                  if lop in [ltop,leop,gtop,geop] then error(131);
  1517. X                  typind := 'a'
  1518. X                end;
  1519. X              power:
  1520. X                begin if lop in [ltop,gtop] then error(132);
  1521. X                  typind := 's'
  1522. X                end;
  1523. X              arrays:
  1524. X                begin
  1525. X                  if not string(lattr.typtr)
  1526. X                then error(134);
  1527. X                  typind := 'm'
  1528. X                end;
  1529. X              records:
  1530. X                begin
  1531. X                  error(134);
  1532. X                  typind := 'm'
  1533. X                end;
  1534. X              files:
  1535. X                begin error(133); typind := 'f' end
  1536. X            end;
  1537. X            case lop of
  1538. X              ltop: gen2(53(*les*),ord(typind),lsize);
  1539. X              leop: gen2(52(*leq*),ord(typind),lsize);
  1540. X              gtop: gen2(49(*grt*),ord(typind),lsize);
  1541. X              geop: gen2(48(*geq*),ord(typind),lsize);
  1542. X              neop: gen2(55(*neq*),ord(typind),lsize);
  1543. X              eqop: gen2(47(*equ*),ord(typind),lsize)
  1544. X            end
  1545. X              end
  1546. X            else error(129)
  1547. X          end;
  1548. X          gattr.typtr := boolptr; gattr.kind := expr
  1549. X        end (*sy = relop*)
  1550. X    end (*expression*) ;
  1551. X
  1552. X    procedure assignment(fcp: ctp);
  1553. X      var lattr: attr;
  1554. X    begin selector(fsys + [becomes],fcp);
  1555. X      if sy = becomes then
  1556. X        begin
  1557. X          if gattr.typtr <> nil then
  1558. X        if (gattr.access<>drct) or (gattr.typtr^.form>power) then
  1559. X          loadaddress;
  1560. X          lattr := gattr;
  1561. X          insymbol; expression(fsys);
  1562. X          if gattr.typtr <> nil then
  1563. X        if gattr.typtr^.form <= power then load
  1564. X        else loadaddress;
  1565. X          if (lattr.typtr <> nil) and (gattr.typtr <> nil) then
  1566. X        begin
  1567. X          if comptypes(realptr,lattr.typtr)and(gattr.typtr=intptr)then
  1568. X            begin gen0(10(*flt*));
  1569. X              gattr.typtr := realptr
  1570. X            end;
  1571. X          if comptypes(lattr.typtr,gattr.typtr) then
  1572. X            case lattr.typtr^.form of
  1573. X              scalar,
  1574. X              subrange: begin
  1575. X                  if debug then checkbnds(lattr.typtr);
  1576. X                  store(lattr)
  1577. X                end;
  1578. X              pointer: begin
  1579. X                 if debug then
  1580. X                   gen2t(45(*chk*),0,maxaddr,nilptr);
  1581. X                 store(lattr)
  1582. X                   end;
  1583. X              power:   store(lattr);
  1584. X              arrays,
  1585. X              records: gen1(40(*mov*),lattr.typtr^.size);
  1586. X              files: error(146)
  1587. X            end
  1588. X          else error(129)
  1589. X        end
  1590. X        end (*sy = becomes*)
  1591. X      else error(51)
  1592. X    end (*assignment*) ;
  1593. X
  1594. X    procedure gotostatement;
  1595. X      var llp: lbp; found: boolean; ttop,ttop1: disprange;
  1596. X    begin
  1597. X      if sy = intconst then
  1598. X        begin
  1599. X          found := false;
  1600. X          ttop := top;
  1601. X          while display[ttop].occur <> blck do ttop := ttop - 1;
  1602. X          ttop1 := ttop;
  1603. X          repeat
  1604. X        llp := display[ttop].flabel;
  1605. X        while (llp <> nil) and not found do
  1606. X          with llp^ do
  1607. X            if labval = val.ival then
  1608. X              begin found := true;
  1609. X            if ttop = ttop1 then
  1610. X              genujpxjp(57(*ujp*),labname)
  1611. X            else (*goto leads out of procedure*) error(399)
  1612. X              end
  1613. X            else llp := nextlab;
  1614. X        ttop := ttop - 1
  1615. X          until found or (ttop = 0);
  1616. X          if not found then error(167);
  1617. X          insymbol
  1618. X        end
  1619. X      else error(15)
  1620. X    end (*gotostatement*) ;
  1621. X
  1622. X    procedure compoundstatement;
  1623. X    begin
  1624. X      repeat
  1625. X        repeat statement(fsys + [semicolon,endsy])
  1626. X        until not (sy in statbegsys);
  1627. X        test := sy <> semicolon;
  1628. X        if not test then insymbol
  1629. X      until test;
  1630. X      if sy = endsy then insymbol else error(13)
  1631. X    end (*compoundstatemenet*) ;
  1632. X
  1633. X    procedure ifstatement;
  1634. X      var lcix1,lcix2: integer;
  1635. X    begin expression(fsys + [thensy]);
  1636. X      genlabel(lcix1); genfjp(lcix1);
  1637. X      if sy = thensy then insymbol else error(52);
  1638. X      statement(fsys + [elsesy]);
  1639. X      if sy = elsesy then
  1640. X        begin genlabel(lcix2); genujpxjp(57(*ujp*),lcix2);
  1641. X          putlabel(lcix1);
  1642. X          insymbol; statement(fsys);
  1643. X          putlabel(lcix2)
  1644. X        end
  1645. X      else putlabel(lcix1)
  1646. X    end (*ifstatement*) ;
  1647. X
  1648. X    procedure casestatement;
  1649. X      label 1;
  1650. X      type cip = ^caseinfo;
  1651. X           caseinfo = packed
  1652. X              record next: cip;
  1653. X                csstart: integer;
  1654. X                cslab: integer
  1655. X              end;
  1656. X      var lsp,lsp1: stp; fstptr,lpt1,lpt2,lpt3: cip; lval: valu;
  1657. X          laddr, lcix, lcix1, lmin, lmax: integer;
  1658. X    begin expression(fsys + [ofsy,comma,colon]);
  1659. X      load; genlabel(lcix);
  1660. X      lsp := gattr.typtr;
  1661. X      if lsp <> nil then
  1662. X        if (lsp^.form <> scalar) or (lsp = realptr) then
  1663. X          begin error(144); lsp := nil end
  1664. X        else if not comptypes(lsp,intptr) then gen0t(58(*ord*),lsp);
  1665. X      genujpxjp(57(*ujp*),lcix);
  1666. X      if sy = ofsy then insymbol else error(8);
  1667. X      fstptr := nil; genlabel(laddr);
  1668. X      repeat
  1669. X        lpt3 := nil; genlabel(lcix1);
  1670. X        if not(sy in [semicolon,endsy]) then
  1671. X          begin
  1672. X        repeat constant(fsys + [comma,colon],lsp1,lval);
  1673. X          if lsp <> nil then
  1674. X            if comptypes(lsp,lsp1) then
  1675. X              begin lpt1 := fstptr; lpt2 := nil;
  1676. X            while lpt1 <> nil do
  1677. X              with lpt1^ do
  1678. X                begin
  1679. X                  if cslab <= lval.ival then
  1680. X                begin if cslab = lval.ival then error(156);
  1681. X                  goto 1
  1682. X                end;
  1683. X                  lpt2 := lpt1; lpt1 := next
  1684. X                end;
  1685. X        1:      new(lpt3);
  1686. X            with lpt3^ do
  1687. X              begin next := lpt1; cslab := lval.ival;
  1688. X                csstart := lcix1
  1689. X              end;
  1690. X            if lpt2 = nil then fstptr := lpt3
  1691. X            else lpt2^.next := lpt3
  1692. X              end
  1693. X            else error(147);
  1694. X          test := sy <> comma;
  1695. X          if not test then insymbol
  1696. X        until test;
  1697. X        if sy = colon then insymbol else error(5);
  1698. X        putlabel(lcix1);
  1699. X        repeat statement(fsys + [semicolon])
  1700. X        until not (sy in statbegsys);
  1701. X        if lpt3 <> nil then
  1702. X          genujpxjp(57(*ujp*),laddr);
  1703. X          end;
  1704. X        test := sy <> semicolon;
  1705. X        if not test then insymbol
  1706. X      until test;
  1707. X      putlabel(lcix);
  1708. X      if fstptr <> nil then
  1709. X        begin lmax := fstptr^.cslab;
  1710. X          (*reverse pointers*)
  1711. X          lpt1 := fstptr; fstptr := nil;
  1712. X          repeat lpt2 := lpt1^.next; lpt1^.next := fstptr;
  1713. X        fstptr := lpt1; lpt1 := lpt2
  1714. X          until lpt1 = nil;
  1715. X          lmin := fstptr^.cslab;
  1716. X          if lmax - lmin < cixmax then
  1717. X        begin
  1718. X          gen2t(45(*chk*),lmin,lmax,intptr);
  1719. X          gen2(51(*ldc*),1,lmin); gen0(21(*sbi*)); genlabel(lcix);
  1720. X          genujpxjp(44(*xjp*),lcix); putlabel(lcix);
  1721. X          repeat
  1722. X            with fstptr^ do
  1723. X              begin
  1724. X            while cslab > lmin do
  1725. X               begin gen0(60(*ujc error*));
  1726. X                 lmin := lmin+1
  1727. X               end;
  1728. X            genujpxjp(57(*ujp*),csstart);
  1729. X            fstptr := next; lmin := lmin + 1
  1730. X              end
  1731. X          until fstptr = nil;
  1732. X          putlabel(laddr)
  1733. X        end
  1734. X          else error(157)
  1735. X        end;
  1736. X        if sy = endsy then insymbol else error(13)
  1737. X    end (*casestatement*) ;
  1738. X
  1739. X    procedure repeatstatement;
  1740. X      var laddr: integer;
  1741. X    begin genlabel(laddr); putlabel(laddr);
  1742. X      repeat statement(fsys + [semicolon,untilsy]);
  1743. X        if sy in statbegsys then error(14)
  1744. X      until not(sy in statbegsys);
  1745. X      while sy = semicolon do
  1746. X        begin insymbol;
  1747. X          repeat statement(fsys + [semicolon,untilsy]);
  1748. X        if sy in statbegsys then error(14)
  1749. X          until not (sy in statbegsys);
  1750. X        end;
  1751. X      if sy = untilsy then
  1752. X        begin insymbol; expression(fsys); genfjp(laddr)
  1753. X        end
  1754. X      else error(53)
  1755. X    end (*repeatstatement*) ;
  1756. X
  1757. X    procedure whilestatement;
  1758. X      var laddr, lcix: integer;
  1759. X    begin genlabel(laddr); putlabel(laddr);
  1760. X      expression(fsys + [dosy]); genlabel(lcix); genfjp(lcix);
  1761. X      if sy = dosy then insymbol else error(54);
  1762. X      statement(fsys); genujpxjp(57(*ujp*),laddr); putlabel(lcix)
  1763. X    end (*whilestatement*) ;
  1764. X
  1765. X    procedure forstatement;
  1766. X      var lattr: attr;  lsy: symbol;
  1767. X          lcix, laddr: integer;
  1768. X            llc: addrrange;
  1769. X    begin llc := lc;
  1770. X      with lattr do
  1771. X        begin typtr := nil; kind := varbl;
  1772. X          access := drct; vlevel := level; dplmt := 0
  1773. X        end;
  1774. X      if sy = ident then
  1775. X        begin searchid([vars],lcp);
  1776. X          with lcp^, lattr do
  1777. X        begin typtr := idtype; kind := varbl;
  1778. X          if vkind = actual then
  1779. X            begin access := drct; vlevel := vlev;
  1780. X              dplmt := vaddr
  1781. X            end
  1782. X          else begin error(155); typtr := nil end
  1783. X        end;
  1784. X          if lattr.typtr <> nil then
  1785. X        if (lattr.typtr^.form > subrange)
  1786. X           or comptypes(realptr,lattr.typtr) then
  1787. X          begin error(143); lattr.typtr := nil end;
  1788. X          insymbol
  1789. X        end
  1790. X      else
  1791. X        begin error(2); skip(fsys + [becomes,tosy,downtosy,dosy]) end;
  1792. X      if sy = becomes then
  1793. X        begin insymbol; expression(fsys + [tosy,downtosy,dosy]);
  1794. X          if gattr.typtr <> nil then
  1795. X          if gattr.typtr^.form <> scalar then error(144)
  1796. X          else
  1797. X            if comptypes(lattr.typtr,gattr.typtr) then
  1798. X              begin load; store(lattr) end
  1799. X            else error(145)
  1800. X        end
  1801. X      else
  1802. X        begin error(51); skip(fsys + [tosy,downtosy,dosy]) end;
  1803. X      if sy in [tosy,downtosy] then
  1804. X        begin lsy := sy; insymbol; expression(fsys + [dosy]);
  1805. X          if gattr.typtr <> nil then
  1806. X          if gattr.typtr^.form <> scalar then error(144)
  1807. X        else
  1808. X          if comptypes(lattr.typtr,gattr.typtr) then
  1809. X            begin load;
  1810. X              if not comptypes(lattr.typtr,intptr) then
  1811. X            gen0t(58(*ord*),gattr.typtr);
  1812. X              align(intptr,lc);
  1813. X              gen2t(56(*str*),0,lc,intptr);
  1814. X              genlabel(laddr); putlabel(laddr);
  1815. X              gattr := lattr; load;
  1816. X              if not comptypes(gattr.typtr,intptr) then
  1817. X            gen0t(58(*ord*),gattr.typtr);
  1818. X              gen2t(54(*lod*),0,lc,intptr);
  1819. X              lc := lc + intsize;
  1820. X              if lc > lcmax then lcmax := lc;
  1821. X              if lsy = tosy then gen2(52(*leq*),ord('i'),1)
  1822. X              else gen2(48(*geq*),ord('i'),1);
  1823. X            end
  1824. X          else error(145)
  1825. X        end
  1826. X      else begin error(55); skip(fsys + [dosy]) end;
  1827. X      genlabel(lcix); genujpxjp(33(*fjp*),lcix);
  1828. X      if sy = dosy then insymbol else error(54);
  1829. X      statement(fsys);
  1830. X      gattr := lattr; load;
  1831. X      if lsy=tosy then gen1t(34(*inc*),1,gattr.typtr)
  1832. X      else  gen1t(31(*dec*),1,gattr.typtr);
  1833. X      store(lattr); genujpxjp(57(*ujp*),laddr); putlabel(lcix);
  1834. X      lc := llc;
  1835. X    end (*forstatement*) ;
  1836. X
  1837. X
  1838. X    procedure withstatement;
  1839. X      var lcp: ctp; lcnt1: disprange; llc: addrrange;
  1840. X    begin lcnt1 := 0; llc := lc;
  1841. X      repeat
  1842. X        if sy = ident then
  1843. X          begin searchid([vars,field],lcp); insymbol end
  1844. X        else begin error(2); lcp := uvarptr end;
  1845. X        selector(fsys + [comma,dosy],lcp);
  1846. X        if gattr.typtr <> nil then
  1847. X          if gattr.typtr^.form = records then
  1848. X        if top < displimit then
  1849. X          begin top := top + 1; lcnt1 := lcnt1 + 1;
  1850. X            with display[top] do
  1851. X              begin fname := gattr.typtr^.fstfld;
  1852. X            flabel := nil
  1853. X              end;
  1854. X            if gattr.access = drct then
  1855. X              with display[top] do
  1856. X            begin occur := crec; clev := gattr.vlevel;
  1857. X              cdspl := gattr.dplmt
  1858. X            end
  1859. X            else
  1860. X              begin loadaddress;
  1861. X            align(nilptr,lc);
  1862. X            gen2t(56(*str*),0,lc,nilptr);
  1863. X            with display[top] do
  1864. X              begin occur := vrec; vdspl := lc end;
  1865. X            lc := lc+ptrsize;
  1866. X            if lc > lcmax then lcmax := lc
  1867. X              end
  1868. X          end
  1869. X        else error(250)
  1870. X          else error(140);
  1871. X        test := sy <> comma;
  1872. X        if not test then insymbol
  1873. X      until test;
  1874. X      if sy = dosy then insymbol else error(54);
  1875. X      statement(fsys);
  1876. X      top := top-lcnt1; lc := llc;
  1877. X    end (*withstatement*) ;
  1878. X
  1879. X      begin (*statement*)
  1880. X    if sy = intconst then (*label*)
  1881. X      begin llp := display[level].flabel;
  1882. X        while llp <> nil do
  1883. X          with llp^ do
  1884. X        if labval = val.ival then
  1885. X          begin if defined then error(165);
  1886. X            putlabel(labname); defined := true;
  1887. X            goto 1
  1888. X          end
  1889. X        else llp := nextlab;
  1890. X        error(167);
  1891. X      1:    insymbol;
  1892. X        if sy = colon then insymbol else error(5)
  1893. X      end;
  1894. X    if not (sy in fsys + [ident]) then
  1895. X      begin error(6); skip(fsys) end;
  1896. X    if sy in statbegsys + [ident] then
  1897. X      begin
  1898. X        case sy of
  1899. X          ident:    begin searchid([vars,field,func,proc],lcp); insymbol;
  1900. X              if lcp^.klass = proc then call(fsys,lcp)
  1901. X              else assignment(lcp)
  1902. X            end;
  1903. X          beginsy:  begin insymbol; compoundstatement end;
  1904. X          gotosy:   begin insymbol; gotostatement end;
  1905. X          ifsy:     begin insymbol; ifstatement end;
  1906. X          casesy:   begin insymbol; casestatement end;
  1907. X          whilesy:  begin insymbol; whilestatement end;
  1908. X          repeatsy: begin insymbol; repeatstatement end;
  1909. X          forsy:    begin insymbol; forstatement end;
  1910. X          withsy:   begin insymbol; withstatement end
  1911. X        end;
  1912. X        if not (sy in [semicolon,endsy,elsesy,untilsy]) then
  1913. X          begin error(6); skip(fsys) end
  1914. X      end
  1915. X      end (*statement*) ;
  1916. X
  1917. X    begin (*body*)
  1918. X      if fprocp <> nil then entname := fprocp^.pfname
  1919. X      else genlabel(entname);
  1920. X      cstptrix := 0; topnew := lcaftermarkstack; topmax := lcaftermarkstack;
  1921. X      putlabel(entname); genlabel(segsize); genlabel(stacktop);
  1922. X      gencupent(32(*ent1*),1,segsize); gencupent(32(*ent2*),2,stacktop);
  1923. X      if fprocp <> nil then (*copy multiple values into local cells*)
  1924. X    begin llc1 := lcaftermarkstack;
  1925. X      lcp := fprocp^.next;
  1926. X      while lcp <> nil do
  1927. X        with lcp^ do
  1928. X          begin
  1929. X        align(parmptr,llc1);
  1930. X        if klass = vars then
  1931. X          if idtype <> nil then
  1932. X            if idtype^.form > power then
  1933. X              begin
  1934. X            if vkind = actual then
  1935. X              begin
  1936. X                gen2(50(*lda*),0,vaddr);
  1937. X                gen2t(54(*lod*),0,llc1,nilptr);
  1938. X                gen1(40(*mov*),idtype^.size);
  1939. X              end;
  1940. X            llc1 := llc1 + ptrsize
  1941. X              end
  1942. X            else llc1 := llc1 + idtype^.size;
  1943. X        lcp := lcp^.next;
  1944. X          end;
  1945. X    end;
  1946. X      lcmax := lc;
  1947. X      repeat
  1948. X    repeat statement(fsys + [semicolon,endsy])
  1949. X    until not (sy in statbegsys);
  1950. X    test := sy <> semicolon;
  1951. X    if not test then insymbol
  1952. X      until test;
  1953. X      if sy = endsy then insymbol else error(13);
  1954. X      llp := display[top].flabel; (*test for undefined labels*)
  1955. X      while llp <> nil do
  1956. X    with llp^ do
  1957. X      begin
  1958. X        if not defined then
  1959. X          begin error(168);
  1960. X        writeln(output); writeln(output,' label ',labval);
  1961. X        write(output,' ':chcnt+16)
  1962. X          end;
  1963. X        llp := nextlab
  1964. X      end;
  1965. X      if fprocp <> nil then
  1966. X    begin
  1967. X      if fprocp^.idtype = nil then gen1(42(*ret*),ord('p'))
  1968. X      else gen0t(42(*ret*),fprocp^.idtype);
  1969. X      align(parmptr,lcmax);
  1970. X      if prcode then
  1971. X        begin writeln(prr,'l',segsize:4,'=',lcmax);
  1972. X          writeln(prr,'l',stacktop:4,'=',topmax)
  1973. X        end
  1974. X    end
  1975. X      else
  1976. X    begin gen1(42(*ret*),ord('p'));
  1977. X      align(parmptr,lcmax);
  1978. X      if prcode then
  1979. SHAR_EOF
  1980. true || echo 'restore of pcom.p failed'
  1981. fi
  1982. echo 'End of  part 2'
  1983. echo 'File pcom.p is continued in part 3'
  1984. echo 3 > _shar_seq_.tmp
  1985. exit 0
  1986. exit 0 # Just in case...
  1987. -- 
  1988. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1989. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1990. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1991. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1992.  
  1993.